package com.bc.bcapi.service.cj;

import cn.hutool.core.util.ReUtil;
import cn.hutool.core.util.StrUtil;
import com.bc.bcapi.dao.*;
import com.bc.bcapi.service.*;
import com.bc.bccore.redis.RedisService;
import com.bc.bccore.util.MyX509TrustManager;
import com.bc.bcmodel.domain.*;
import com.bc.commoncore.util.*;
import com.bc.commonentity.common.JsonResult;
import com.bc.commonentity.enums.HttpReturnRnums;
import com.bc.commonentity.enums.SeqNameEnum;
import org.apache.http.HttpHost;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.impl.conn.DefaultProxyRoutePlanner;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.io.*;
import java.math.BigDecimal;
import java.net.URL;
import java.net.URLConnection;
import java.security.KeyManagementException;
import java.security.NoSuchAlgorithmException;
import java.sql.Struct;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.concurrent.TimeUnit;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import java.io.IOException;
import java.io.InputStream;
import java.net.URL;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import javax.net.ssl.*;

import static com.bc.commoncore.util.HttpDownload.readInputStream;

/**
 * @Name GenerationBinan
 * @Description TODO
 * @Author douhaichao
 * @Date 2019/5/16 20:58
 * @Version 1.0
 **/
@Service
public class GenerationBinanService {
    private final static Logger log = LoggerFactory.getLogger(GenerationBinanService.class);

    @Resource
    T_SequenceService t_sequenceService;
    @Resource
    T_User_seller_infoMapper t_user_seller_infoMapper;
    @Resource
    T_ProjectMapper t_projectMapper;
    @Resource
    T_CountryMapper t_countryMapper;
    @Resource
    T_ProjectMapper t_ProjectMapper;
    @Resource
    T_Project_ceokycService t_project_ceokycService;
    @Resource
    T_Project_contactService t_project_contactService;
    @Resource
    T_Project_cjMapper t_project_cjMapper;
    @Resource
    RedisService redisService;
    @Resource
    T_Project_teamMapper t_project_teamMapper;
    @Resource
    T_Project_enMapper t_project_enMapper;

    private static final String domain = "https://info.binance.com/";
    private static String downloadLocalPath = "C:\\Users\\douhaichao\\Desktop\\attr\\";
//    private static String downloadLocalPath = "/data/img/ba/";

    private static String cjProjectName = "ba";

    public JsonResult generationIco() {
//        downLoadFromUrlHttps("https://resource.bnbstatic.com/books/20180205/1517833908664.pdf",
//                "1517833908664.pdf", downloadLocalPath + cjProjectName + "\\whitepaper\\");
//        String bps = "/" + cjProjectName + "/whitepaper/1517833908664.pdf";

        list("http://www.180yg.com/binan.html");
        return new JsonResult(HttpReturnRnums.Success);
    }

    private void list(String url) {
        String key = "generation_list20190517";
        String str = redisService.get(key);
        List<String> list = new ArrayList<String>();
        if (StringUtils.isEmpty(str)) {
//            url = domain + url;
            String listHtml = cn.hutool.http.HttpUtil.get(url);
            Matcher matcher = Pattern.compile("<span class=\"fullName\">(.*?)</span>").matcher(listHtml);
            while (matcher.find()) {
                String value = matcher.group(1);
                value = value.toLowerCase();
                value = value.replace(" ", "-");
                list.add(value);
            }
            str = JsonUtil.obj2string(list);
            redisService.set(key, str);
        } else {
            list = JsonUtil.str2list(str, String.class);
        }

        for (String ico_name :
                list) {
            String detaiUrl = domain + "cn/currencies/" + ico_name;
            try {
                detail(detaiUrl, ico_name);
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    }

    private void detail(String url, String ico_name) {
        String pid = t_projectMapper.getPidByIcoName(ico_name);
        if (!StringUtils.isEmpty(pid)) {
            System.out.print("已经存在" + pid);
            return;
        }
        //from_url
//        System.setProperty("https.protocols", "TLSv1.2,TLSv1.1,SSLv3");
//        String html = cn.hutool.http.HttpUtil.get(url);
//        String html = HttpUtil.sendGet(url, "");
//        String html = getData(url);
        String html = HttpRequest(url);
        if (StrUtil.isEmpty(html)) {
            return;
        }
        String ticker = ReUtil.get("<div class=\"cryptoName\"><img alt=\"(?:.*?)\" src=\"(?:.*?)\"/><h1>(?:.*?)</h1><div class=\"instro\">(.*?)</div>", html, 1);
        String logo_url = ReUtil.get("<div class=\"cryptoName\"><img alt=\"(?:.*?)\" src=\"(.*?)\"/><h1>(?:.*?)</h1><div class=\"instro\">(.*?)</div>", html, 1);
        String token_price = ReUtil.get("<div class=\"ix71fe-7(?:.*?)\">(.*?)</div>", html, 1);
        token_price = StrUtil.isEmpty(token_price) ? "0" : token_price.replace("$", "").replace("-", "");
//        String fundraising_goal = "0";
        String total_tokens = ReUtil.get("浏览器</th></tr><tr><td>(.*?)</td><td>(?:.*?)</td><td>().*?</td>", html, 1);
        total_tokens = StrUtil.isEmpty(total_tokens) ? "0" : total_tokens.replace(",", "").replace("-", "");
        String start_time = ReUtil.get("浏览器</th></tr><tr><td>(?:.*?)</td><td>(?:.*?)</td><td>(.*?)</td>", html, 1);

        String logo = downloadImg(logo_url, "logos");

        //社交开始
        List<String> listSj = ReUtil.getAllGroups(Pattern.compile("<a class=\"s1f3siel-4 BppNm\" href=\"(.*?)\" target=\"_blank\" rel=\"noopener noreferrer\">"), html);
        HashMap<String, String> mapContract = new HashMap<String, String>();
        for (String item :
                listSj) {
            String key = getContactKey(item);
            if (StringUtils.isEmpty(key)) {
                continue;
            }
            mapContract.put(key, item);
        }
        //社交结束

        String website = ReUtil.getGroup1("<a class=\"s1re75us-3 hBLTSO\" href=\"(.*?)\" target=\"_blank\">Website</a>", html);

        //Whitepaper
        String whitepaper_url = ReUtil.getGroup1("<div class=\"s1qusdff-6 eLRHsi\"><a href=\"(.*?)\" target=\"_blank\">", html);
        String whitepaper = downloadWhitePaper(whitepaper_url, "cn");

        /*team*/
        List<T_Project_teamModel> listTeam = new ArrayList<T_Project_teamModel>();
        List<String> listTeamHtml = ReUtil.getAllGroups(
                Pattern.compile(
                        "<div class=\"s1fae2gn-4 cZhnlE\"><img src=\"(.*?)\" alt=\"(.*?)\"/><h3 title=\"(.*?)\">(.*?)</h3><h4([\\s\\S]+?)</h4><p>(.*?)</p><span class=\"s1fae2gn-3 eFAAvA\">更多<i class=\"iconfont icon-jiantouxia s1xv7c9m-0 awGMA\" type=\"jiantouxia\" size=\"16\" color=\"\"></i></span>([\\s\\S]+?)</div>"), html);
        String head_imgArr = "";
        for (String item :
                listTeamHtml) {
            T_Project_teamModel t_project_teamModel = new T_Project_teamModel();
            String head_img = ReUtil.getGroup1("<img src=\"(.*?)\" alt=\"(.*?)\"/>", item);
            if (!StrUtil.isEmpty(head_img)) {
                head_imgArr += head_img + ",";
            }
            head_img = downloadImg(head_img, "team");
            t_project_teamModel.setHead_img(StrUtil.isEmpty(head_img) ? "" : head_img);
            String uname = ReUtil.getGroup1("<img src=\"(?:.*?)\" alt=\"(.*?)\"/>", item);
            t_project_teamModel.setUname(StrUtil.isEmpty(uname) ? "" : uname);
            String udesc = ReUtil.getGroup1("<p>(.*?)</p>", item);
            t_project_teamModel.setUdesc(StrUtil.isEmpty(udesc) ? "" : udesc);
            String utitle = ReUtil.getGroup1("<h4 title=\"(.*?)\">(.*?)</h4>", item);
            t_project_teamModel.setUtitle(StrUtil.isEmpty(utitle) ? "" : utitle);
            String linkedin = ReUtil.getGroup1("<a class=\"s1fae2gn-2 eiNsjR\" href=\"(.*?)\" target=\"_blank\" alt=\"(.*?)\" rel=\"noopener noreferrer\">", item);
            t_project_teamModel.setLinkedin(StrUtil.isEmpty(linkedin) ? "" : linkedin);
            listTeam.add(t_project_teamModel);
        }
        //注册用户B
        String user_id = getUserId(ico_name);

        /*英文信息*/
        //获取描述
        String description_cn = ReUtil.getGroup1("<div class=\"s1qusdff-3 kTUNKs\">([\\s\\S]+?)</div></div><div class=\"s1fae2gn-1 larBpH\">", html);
        description_cn = StrUtil.isEmpty(description_cn) ? "" :
                description_cn.replace("<p>", "").replace("</p>", "");
        String enUrl = url.replace("https://info.binance.com/cn/", "https://info.binance.com/en/");
        String enHtml = HttpRequest(enUrl);
        String description_en = ReUtil.getGroup1("<div class=\"s1qusdff-3 kTUNKs\">([\\s\\S]+?)</div></div><div class=\"s1fae2gn-1 larBpH\">", enHtml);
        description_en = StrUtil.isEmpty(description_en) ? "" :
                description_en.replace("<p>", "").replace("</p>", "");

        String whitepaper_url_en = ReUtil.getGroup1("<div class=\"s1qusdff-6 eLRHsi\"><a href=\"(.*?)\" target=\"_blank\">", enHtml);
        String whitepaper_en = downloadWhitePaper(whitepaper_url_en, "en");
        /*英文信息结束*/

        //创建项目
        pid = setProject(user_id, ico_name, logo,
                whitepaper,
                cn.hutool.core.date.DateUtil.parse(start_time),
                description_cn, description_en,
                total_tokens,
                token_price,
                website, ticker, mapContract,
                listTeam, whitepaper_en
        );

        setProjectCJ(pid, url, "binan.com", whitepaper_url, whitepaper_url_en, head_imgArr, logo_url);
    }

    private void setProjectCJ(String pid, String from_url, String platform,
                              String from_whiltePaper, String whitepaper_en,
                              String head_img, String logo_url) {
        if (StringUtils.isEmpty(pid)) {
            return;
        }
        T_Project_cjModel t_project_cjModel = new T_Project_cjModel();
        t_project_cjModel.setPid(pid);
//        int count = t_project_cjMapper.count(t_project_cjModel);
//        if (count > 0) {
//            return;
//        }
        t_project_cjModel.setFrom_url(from_url);
        t_project_cjModel.setFrom_whitepaper(from_whiltePaper);
        t_project_cjModel.setPlatform(platform);
        t_project_cjModel.setWhitepaper_en(whitepaper_en);
        t_project_cjModel.setHead_img(head_img);
        t_project_cjModel.setLogo_url(logo_url);
        t_project_cjMapper.insert(t_project_cjModel);
    }

    /**
     * 添加项目
     */
    private String setProject(
            String user_id, String ico_name, String logo, String white_paper,
            Date start_time,
            String pdesc, String pdesc_en,
            String totalToken, String tokenPrice,
            String officialSite, String ticker,
            HashMap<String, String> mapContract,
            List<T_Project_teamModel> listTeam,
            String whitepaper_en
    ) {
        String pid = t_projectMapper.getPidByIcoName(ico_name);
        //默认是修改
        boolean isAdd = false;
        if (StringUtils.isEmpty(pid)) {
            isAdd = true;
            pid = t_sequenceService.genSequence(SeqNameEnum.PROJECT_ID);
        }
        T_ProjectModel projectModel = new T_ProjectModel();
        projectModel.setIco_name(ico_name);
        projectModel.setTicker(ticker);
        projectModel.setPid(pid);
        projectModel.setStatus(-1);
        projectModel.setImg_project_logo(logo);
        projectModel.setImg_white_paper(white_paper);
        projectModel.setUser_id(user_id);
        projectModel.setPid(pid);
        projectModel.setStart_time(start_time);
//        projectModel.setEnd_time(end_time);
        projectModel.setPdesc(pdesc);
        projectModel.setTotal_tokens(StringUtils.isEmpty(totalToken) ? BigDecimal.ZERO : new BigDecimal(totalToken.replace(",", "")));
        projectModel.setToken_price(StringUtils.isEmpty(tokenPrice) ? BigDecimal.ZERO : new BigDecimal(tokenPrice.replace(",", "")));
        projectModel.setAccepts("BTC,ETH");
        projectModel.setOfficicl_web(officialSite);
        projectModel.setTicker(ticker);
        projectModel.setTid("PT000006006");
        //主要成员介绍
        List<T_Project_contactModel> listContact = getContract(mapContract, pid);
//        T_Project_ceokycModel t_project_ceokycModel = new T_Project_ceokycModel();
//        t_project_ceokycModel.setPid(pid);
        T_Project_enModel t_project_enModel = new T_Project_enModel();
        t_project_enModel.setPdesc(pdesc_en);
        t_project_enModel.setPid(projectModel.getPid());
        t_project_enModel.setWhitepaper_en(whitepaper_en);
        final String tpid = pid;
        listTeam.forEach(item -> {
            item.setPid(tpid);
        });
        if (isAdd) {
            //insert
            t_ProjectMapper.insert(projectModel);
//            t_project_ceokycService.insert(t_project_ceokycModel);
            t_project_enMapper.insert(t_project_enModel);

        } else {
            //update
            projectModel.setModify_time(DateUtil.getToday());
            t_ProjectMapper.update(projectModel);
//            t_project_ceokycService.update(t_project_ceokycModel);
            t_project_contactService.delete(pid);
            t_project_teamMapper.delete(pid);
            t_project_enMapper.update(t_project_enModel);
        }
        if (listContact != null && listContact.size() > 0) {
            t_project_contactService.insertBatch(listContact);

        }
        if (listTeam != null && listTeam.size() > 0) {

            t_project_teamMapper.insertBatch(listTeam);
        }
        return pid;
    }

    private List<T_Project_contactModel>
    getContract(HashMap<String, String> mapContract, String pid) {
        List<T_Project_contactModel> list = new ArrayList<T_Project_contactModel>();
        if (mapContract.size() <= 0) {
            return list;
        }
        for (String key :
                mapContract.keySet()) {
            String value = mapContract.get(key);
            T_Project_contactModel t_project_contactModel = new T_Project_contactModel();
            t_project_contactModel.setPid(pid);
            if (key.toLowerCase().equals("telegram")) {
                t_project_contactModel.setContact_name("telegram");
                t_project_contactModel.setContact_value(value);
            } else if (key.toLowerCase().equals("github")) {
                t_project_contactModel.setContact_name("github");
                t_project_contactModel.setContact_value(value);
            } else if (key.toLowerCase().equals("biyong")) {
                t_project_contactModel.setContact_name("biyong");
                t_project_contactModel.setContact_value(value);
            } else if (key.toLowerCase().equals("facebook")) {
                t_project_contactModel.setContact_name("facebook");
                t_project_contactModel.setContact_value(value);
            } else if (key.toLowerCase().equals("slack")) {
                t_project_contactModel.setContact_name("slack");
                t_project_contactModel.setContact_value(value);
            } else if (key.toLowerCase().equals("twitter")) {
                t_project_contactModel.setContact_name("twitter");
                t_project_contactModel.setContact_value(value);
            } else {
                continue;
            }
            list.add(t_project_contactModel);
        }
        return list;
    }

    private String getUserId(String ico_name) {
        //去项目里查询当前ico_name是否存在，存在直接返回项目里的user_id;
//        t_user_seller_infoMapper.getUserIdByIcoName();
//        t_user_seller_infoMapper.getUserIdByName()
        T_User_seller_infoModel t_user_seller_infoModel = new T_User_seller_infoModel();
        t_user_seller_infoModel.setName(ico_name);
        T_User_seller_infoModel model = t_user_seller_infoMapper.findByNamedParam(t_user_seller_infoModel);
        if (model != null) {
            return model.getUser_id();
        }
//        String userId = t_projectMapper.getUserIdByIcoName(ico_name);
//        if (!StringUtils.isEmpty(userId)) {
//            return userId;
//        }
        //注册用户
        String userId = t_sequenceService.genSequence(SeqNameEnum.USER_INFO_SEQ);
//        T_User_seller_infoModel t_user_seller_infoModel = new T_User_seller_infoModel();
        t_user_seller_infoModel.setUser_id(userId);
        t_user_seller_infoModel.setStatus("1");
        t_user_seller_infoModel.setEmail(userId + "@marvel.com");
        t_user_seller_infoModel.setName(ico_name);
        t_user_seller_infoModel.setNick_name(ico_name);
        t_user_seller_infoModel.setRequest_from("icowatchlist.com");
        t_user_seller_infoModel.setPassword(Digest.signMD5("superhero520", Digest.ENCODE));
        t_user_seller_infoMapper.insert(t_user_seller_infoModel);
        return userId;
    }

    //下载白皮书--白皮书可能文件过大，就直接存库里，然后用迅雷批量下载得了。
    private String downloadWhitePaper(String url, String language) {
        if (StrUtil.isEmpty(url) || url.length() < 3) {
            return "";
        }
        String fileName = url.substring(url.lastIndexOf('/') + 1);
//            HttpDownload.downLoadFromUrl
//        downLoadFromUrlHttps(url, fileName, downloadLocalPath + cjProjectName + "\\whitepaper\\");
        return "/" + cjProjectName + "/whitepaper/" + language + "/" + fileName;
    }

    //下载LOGO
    private String downloadImg(String url, String type) {
        if (StrUtil.isEmpty(url) || url.length() < 3) {
            return "";
        }
        String fileName = url.substring(url.lastIndexOf('/') + 1);
//            HttpDownload.downLoadFromUrl
//        downLoadFromUrlHttps(url, fileName,
//                downloadLocalPath + cjProjectName + "\\" + type + "\\");
        return "/" + cjProjectName + "/" + type + "/" + fileName;
    }

    private String getContactKey(String url) {
        if (StringUtils.isEmpty(url)) {
            return "";
        }
        if (url.contains("twitter")) {
            return "twitter";
        }
        if (url.contains("facebook")) {
            return "facebook";
        }
        if (url.contains("t.me")) {
            return "telegram";
        }
        if (url.contains("youtube")) {
            return "youtube";
        }
        if (url.contains("linkedin")) {
            return "linkedin";
        }
        if (url.contains("reddit")) {
            return "reddit";
        }
        if (url.contains("medium")) {
            return "medium";
        }
        if (url.contains("instagram")) {
            return "instagram";
        }
        if (url.contains("github")) {
            return "github";
        }
        if (url.contains("bitcointalk")) {
            return "bitcointalk";
        }
        return "";
    }

    private static String HttpRequest(String requestUrl) {
        StringBuffer buffer = null;
        BufferedReader bufferedReader = null;
        InputStreamReader inputStreamReader = null;
        InputStream inputStream = null;
        HttpsURLConnection httpUrlConn = null;
        // 建立并向网页发送请求
        try {
            TrustManager[] tm = {new MyX509TrustManager()};
            SSLContext sslContext = SSLContext.getInstance("SSL", "SunJSSE");
            sslContext.init(null, tm, new java.security.SecureRandom());
            // 从上述SSLContext对象中得到SSLSocketFactory对象
            SSLSocketFactory ssf = sslContext.getSocketFactory();

            URL url = new URL(requestUrl);
            // 描述状态
            httpUrlConn = (HttpsURLConnection) url.openConnection();
            httpUrlConn.setSSLSocketFactory(ssf);
            httpUrlConn
                    .setRequestProperty("User-Agent", "Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/61.0.3163.100 Safari/537.36)");
            //防止报403错误。
            httpUrlConn.setDoOutput(true);
            httpUrlConn.setDoInput(true);
            httpUrlConn.setUseCaches(false);
            // 请求的类型
            httpUrlConn.setRequestMethod("GET");
            // 获取输入流
            inputStream = httpUrlConn.getInputStream();
            inputStreamReader = new InputStreamReader(inputStream, "utf-8");
            bufferedReader = new BufferedReader(inputStreamReader);
            // 从输入流读取结果
            buffer = new StringBuffer();
            String str = null;
            while ((str = bufferedReader.readLine()) != null) {
                buffer.append(str);
            }
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            // 释放资源
            if (bufferedReader != null) {
                try {
                    bufferedReader.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
            if (inputStreamReader != null) {
                try {
                    inputStreamReader.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
            if (inputStream != null) {
                try {
                    inputStream.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
            if (httpUrlConn != null) {
                httpUrlConn.disconnect();
            }
        }
        return buffer.toString();
    }

    public static void downLoadFromUrlHttps(String urlStr, String fileName, String savePath) {
        try {
            // 创建SSLContext
            SSLContext sslContext = SSLContext.getInstance("SSL");
            TrustManager[] tm = {new MyX509TrustManager()};
            // 初始化
            sslContext.init(null, tm, new java.security.SecureRandom());
            // 获取SSLSocketFactory对象
            SSLSocketFactory ssf = sslContext.getSocketFactory();
            // url对象
            URL url = new URL(urlStr);
            // 打开连接
            HttpsURLConnection conn = (HttpsURLConnection) url.openConnection();
            /**
             * 这一步的原因: 当访问HTTPS的网址。您可能已经安装了服务器证书到您的JRE的keystore
             * 但是服务器的名称与证书实际域名不相等。这通常发生在你使用的是非标准网上签发的证书。
             *
             * 解决方法：让JRE相信所有的证书和对系统的域名和证书域名。
             *
             * 如果少了这一步会报错:java.io.IOException: HTTPS hostname wrong: should be <localhost>
             */
            conn.setHostnameVerifier(new MyX509TrustManager().new TrustAnyHostnameVerifier());
            // 设置一些参数
            conn.setDoOutput(true);
            conn.setDoInput(true);
            conn.setUseCaches(false);
            // 设置当前实例使用的SSLSoctetFactory
            conn.setSSLSocketFactory(ssf);
            conn.connect();

            // 得到输入流
            InputStream inputStream = conn.getInputStream();
            byte[] getData = readInputStream(inputStream);
            // 文件保存位置
            File saveDir = new File(savePath);
            if (!saveDir.exists()) {
                saveDir.mkdirs();
            }
            //输出流
            File file = new File(saveDir + File.separator + fileName);
            FileOutputStream fos = new FileOutputStream(file);
            fos.write(getData);
            if (fos != null) {
                fos.close();
            }
            if (inputStream != null) {
                inputStream.close();
            }
        } catch (NoSuchAlgorithmException e) {
            e.printStackTrace();
        } catch (KeyManagementException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

}
